package com.zhixinglu.spring.boot.thread.threadpool;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 * NamedThreadFactory
 * </p>
 *
 * @author weixin
 * @date 2023/3/24 14:57
 */
@Slf4j
public class NamedThreadFactory implements ThreadFactory, Thread.UncaughtExceptionHandler {

    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String threadNamePrefix;
    private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler;

    public NamedThreadFactory(String threadNamePrefix) {
        this(threadNamePrefix, null);
    }

    public NamedThreadFactory(String threadNamePrefix, Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
        this.threadNamePrefix = threadNamePrefix;
        this.uncaughtExceptionHandler = uncaughtExceptionHandler;
    }

    @Override
    public Thread newThread(Runnable runnable) {
        String threadName = threadNamePrefix + "-" + threadNumber.getAndIncrement();
        Thread thread = new Thread(runnable, threadName);
        thread.setUncaughtExceptionHandler(this);
        thread.setDaemon(true);
        return thread;
    }

    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        System.err.println("Uncaught exception in thread " + thread.getName() + ":");
        throwable.printStackTrace(System.err);
        if (uncaughtExceptionHandler != null) {
            uncaughtExceptionHandler.uncaughtException(thread, throwable);
        }
    }

}
